package com.huayal.mall.product.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.huayal.common.constant.ProductConstant;
import com.huayal.common.utils.R;
import com.huayal.common.vo.SkuReductionDTO;
import com.huayal.common.vo.SpuBoundsDTO;
import com.huayal.common.vo.es.SkuESModel;
import com.huayal.common.vo.es.SkuHasStockDTO;
import com.huayal.mall.product.dao.SpuInfoDescDao;
import com.huayal.mall.product.entity.*;
import com.huayal.mall.product.fegin.CouponFeginService;
import com.huayal.mall.product.fegin.ESFeginService;
import com.huayal.mall.product.fegin.WareFeginService;
import com.huayal.mall.product.service.*;
import com.huayal.mall.product.vo.*;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.huayal.common.utils.PageUtils;
import com.huayal.common.utils.Query;

import com.huayal.mall.product.dao.SpuInfoDao;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;


@Service("spuInfoService")
public class SpuInfoServiceImpl extends ServiceImpl<SpuInfoDao, SpuInfoEntity> implements SpuInfoService {

    @Resource
    SpuInfoDescDao spuInfoDescDao;

    @Autowired
    SpuImagesService spuImagesService;

    @Autowired
    ProductAttrValueService productAttrValueService;

    @Autowired
    AttrService attrService;

    @Autowired
    SkuInfoService skuInfoService;

    @Autowired
    SkuImagesService skuImagesService;

    @Autowired
    SkuSaleAttrValueService skuSaleAttrValueService;

    @Autowired
    CouponFeginService couponFeginService;

    @Autowired
    CategoryService categoryService;

    @Autowired
    BrandService brandService;

    @Autowired
    WareFeginService wareFeginService;

    @Autowired
    ESFeginService esFeginService;


    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<SpuInfoEntity> page = this.page(
                new Query<SpuInfoEntity>().getPage(params),
                new QueryWrapper<SpuInfoEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public PageUtils queryPageByCondition(Map<String, Object> params) {
        QueryWrapper<SpuInfoEntity> wrapper = new QueryWrapper<>();

        String key = (String)params.get("key");
        if (StringUtils.isNotEmpty(key)){
            wrapper.and((w)->{
               w.eq("id",key).
                       or().like("spu_name",key).
                       or().like("spu_description",key);
            });
        }

        String status = (String)params.get("status");
        if (StringUtils.isNotEmpty(status)){
            wrapper.eq("publish_status",status);
        }
        String brandId = (String)params.get("brandId");
        if (StringUtils.isNotEmpty(brandId)&&!"0".equals(brandId)){
            wrapper.eq("brand_id",brandId);
        }
        String catelogId = (String)params.get("catelogId");
        if (StringUtils.isNotEmpty(catelogId)&&!"0".equals(catelogId)){
            wrapper.eq("catalog_id",catelogId);
        }

        IPage<SpuInfoEntity> page = this.page(
                new Query<SpuInfoEntity>().getPage(params),
                wrapper
        );
//        return new PageUtils(page);

        List<SpuInfoVo> list = page.getRecords().stream().map(item -> {
            SpuInfoVo spuInfoVo = new SpuInfoVo();
            BeanUtils.copyProperties(item,spuInfoVo);
            CategoryEntity categoryEntity = categoryService.getById(item.getCatalogId());
            BrandEntity brandEntity = brandService.getById(item.getBrandId());
            spuInfoVo.setCatalogName(categoryEntity.getName());
            spuInfoVo.setBrandName(brandEntity.getName());
            return spuInfoVo;
        }).collect(Collectors.toList());
        IPage<SpuInfoVo> newPage = new Page<SpuInfoVo>();
        BeanUtils.copyProperties(page,newPage);
        newPage.setRecords(list);
        return new PageUtils(newPage);
    }

    /**
     * 保存商品的发布信息
     * @param spuInfoVo
     */
    @Transactional
    @Override
    public void saveSpuInfo(SpuInfoVo spuInfoVo) {
        //1，保存spu的基本信息 pms_spu_info
        SpuInfoEntity spuInfoEntity = new SpuInfoEntity();
        BeanUtils.copyProperties(spuInfoVo,spuInfoEntity);
        spuInfoEntity.setCreateTime(new Date());
        spuInfoEntity.setUpdateTime(new Date());
        this.save(spuInfoEntity);
        Long spuId = spuInfoEntity.getId();
        //2，保存spu的详细信息 pms_spu_info_desc
        List<String> decripts = spuInfoVo.getDecript();
        SpuInfoDescEntity spuInfoDescEntity = new SpuInfoDescEntity();
        spuInfoDescEntity.setSpuId(spuId); //如果id不是自增的，需要设置：@TableId(type=IdType.INPUT)
        spuInfoDescEntity.setDecript(String.join(",",decripts));//huayal9146*
        spuInfoDescDao.insert(spuInfoDescEntity);
        //3，保存图集信息 pms_spu_images
        List<String> images = spuInfoVo.getImages();
        List<SpuImagesEntity> spuImagesEntities = images.stream().map(imageUrl -> {
            SpuImagesEntity spuImagesEntity = new SpuImagesEntity();
            spuImagesEntity.setSpuId(spuId);
            spuImagesEntity.setImgUrl(imageUrl);
            return spuImagesEntity;
        }).collect(Collectors.toList());
        spuImagesService.saveBatch(spuImagesEntities);
        //4，保存规格参数 pms_product_attr_value
        List<BaseAttrs> baseAttrs = spuInfoVo.getBaseAttrs();
        List<ProductAttrValueEntity> productAttrValueEntities = baseAttrs.stream().map(item -> {
            ProductAttrValueEntity productAttrValueEntity = new ProductAttrValueEntity();
            productAttrValueEntity.setSpuId(spuId);
            productAttrValueEntity.setAttrId(item.getAttrId());
            //需要查询attrName
            AttrEntity attrEntity = attrService.getById(item.getAttrId());
            if (attrEntity!=null)productAttrValueEntity.setAttrName(attrEntity.getAttrName());
            productAttrValueEntity.setAttrValue(item.getAttrValues());
            productAttrValueEntity.setQuickShow(item.getShowDesc());
            return productAttrValueEntity;
        }).collect(Collectors.toList());
        productAttrValueService.saveBatch(productAttrValueEntities);

        //5，保存当前的spu对应的所有sku信息
        List<Skus> skus = spuInfoVo.getSkus();
        if (skus!=null&&skus.size()>0){
            //5.1 保存sku的基本信息 pms_sku_info
            skus.forEach((item)->{
                SkuInfoEntity skuInfoEntity = new SkuInfoEntity();
                BeanUtils.copyProperties(item,skuInfoEntity);
                skuInfoEntity.setSpuId(spuId);
                skuInfoEntity.setBrandId(spuInfoVo.getBrandId());
                skuInfoEntity.setCatalogId(spuInfoVo.getCatalogId());
                skuInfoEntity.setSaleCount(0L);
                List<Images> images1 = item.getImages();
                String defaultImage="";
                for (Images images2:images1){
                    if (images2.getDefaultImg()==1){
                        //表示默认
                        defaultImage=images2.getImgUrl();
                        break;
                    }
                }
                skuInfoEntity.setSkuDefaultImg(defaultImage);
                skuInfoService.save(skuInfoEntity);

                //5.2 保存sku的图片信息 pms_sku_images
                List<SkuImagesEntity> skuImagesEntities = images1.stream().map(images2 -> {
                    SkuImagesEntity skuImagesEntity = new SkuImagesEntity();
                    BeanUtils.copyProperties(images2,skuImagesEntity);
                    skuImagesEntity.setSkuId(skuInfoEntity.getSkuId());

                    return skuImagesEntity;
                }).filter(img->{
                    return img.getDefaultImg()==1;
                }).collect(Collectors.toList());
                skuImagesService.saveBatch(skuImagesEntities);
                //5.3 保存满减、折扣、会员价信息 mall-sms：sms_sku_ladder sms_sku_full_reduction sms_member_price
                //需要进行远程调用 OpenFegin
                SkuReductionDTO skuReductionDTO = new SkuReductionDTO();
                BeanUtils.copyProperties(item,skuReductionDTO);
                skuReductionDTO.setSkuId(skuInfoEntity.getSkuId());
                //处理memberPrice
                List<MemberPrice> memberPrice = item.getMemberPrice();
                if (memberPrice!=null&&memberPrice.size()>0){
                    List<com.huayal.common.vo.MemberPrice> memberPrices = memberPrice.stream().map(memberPrice1 -> {
                        com.huayal.common.vo.MemberPrice memberPrice2 = new com.huayal.common.vo.MemberPrice();
                        BeanUtils.copyProperties(memberPrice1,memberPrice2);
                        return memberPrice2;
                    }).collect(Collectors.toList());
                    skuReductionDTO.setMemberPrice(memberPrices);
                }
                R r = couponFeginService.saveReductionInfo(skuReductionDTO);
                if (r.getCode()!=0){
                    log.error("调用Coupon服务处理满减、折扣、会员信息失败...");
                }

                //5.4 sku的销售属性信息 pms_sku_sale_attr_value
                List<Attr> attr = item.getAttr();
                List<SkuSaleAttrValueEntity> skuSaleAttrValueEntities = attr.stream().map(attr1 -> {
                    SkuSaleAttrValueEntity skuSaleAttrValueEntity = new SkuSaleAttrValueEntity();
                    BeanUtils.copyProperties(attr1,skuSaleAttrValueEntity);
                    skuSaleAttrValueEntity.setSkuId(skuInfoEntity.getSkuId());
                    return skuSaleAttrValueEntity;
                }).collect(Collectors.toList());
                skuSaleAttrValueService.saveBatch(skuSaleAttrValueEntities);
            });

        }

        //6，保存spu的积分信息 mall-sms：sms_spu_bounds
        Bounds bounds = spuInfoVo.getBounds();
        SpuBoundsDTO spuBoundsDTO = new SpuBoundsDTO();
        BeanUtils.copyProperties(bounds,spuBoundsDTO);
        spuBoundsDTO.setSpuId(spuId);
        R r = couponFeginService.saveSpuBounds(spuBoundsDTO);
        if (r.getCode()!=0){
            log.error("调用Coupon服务保存spu的积分信息失败...");
        }

    }

    /**
     * 根据传过来的spuId获取相关数据，存入ES，然后修改上架状态
     * 大致流程：
     * 1，根据spuId获取相关数据 封装到对应的对象中
     * 2，将封装的对象存储到ES中 --->调用远程的mall-search服务
     * 3，获取存储状态，成功，修改上架状态
     * @param spuId
     */
    @Override
    @Transactional
    public R spuUp(Long spuId) {
        //1，根据spuId查询相关信息
//        List<SkuESModel> skuESModels = new ArrayList<>();

        List<SkuInfoEntity> skuInfoEntities = skuInfoService.list(new QueryWrapper<SkuInfoEntity>().eq("spu_id", spuId));

        //根据skuIds批量查询hasStock
        List<Long> skuIds = skuInfoEntities.stream().map(item -> {
            return item.getSkuId();
        }).collect(Collectors.toList());
        List<SkuHasStockDTO> list = wareFeginService.SkuHasStock(skuIds);
        Map<Long, Boolean> map = list.stream().collect(Collectors.toMap((SkuHasStockDTO::getSkuId), (SkuHasStockDTO::getHasStock)));

        List<SkuESModel> skuESModels = skuInfoEntities.stream().map(item -> {
            //sku 主体
            SkuESModel skuESModel = new SkuESModel();
            Long skuId = item.getSkuId();
            skuESModel.setSkuId(skuId);
            skuESModel.setSpuId(spuId);
            skuESModel.setSkuTitle(item.getSkuTitle());
            skuESModel.setSkuPrice(item.getPrice());
            skuESModel.setSkuImg(item.getSkuDefaultImg());
            skuESModel.setSaleCount(item.getSaleCount());

            //hasStock
            skuESModel.setHasStock(map.get(skuId));

            //hotScore
            skuESModel.setHotScore(0l);

            //brand
            Long brandId = item.getBrandId();
            BrandEntity brandEntity = brandService.getById(brandId);
            skuESModel.setBrandId(brandId);
            skuESModel.setBrandName(brandEntity.getName());
            skuESModel.setBrandImg(brandEntity.getLogo());

            //catelog
            Long catalogId = item.getCatalogId();
            CategoryEntity categoryEntity = categoryService.getById(catalogId);
            skuESModel.setCatelogId(catalogId);
            skuESModel.setCatelogName(categoryEntity.getName());

            //attrs
            List<Attr> attrInfos=attrService.getAttrInfos(catalogId);
            if (attrInfos!=null&&attrInfos.size()>0){
                List<SkuESModel.Attr> attrs = attrInfos.stream().map(attr -> {
                    SkuESModel.Attr attr1 = new SkuESModel.Attr();
                    BeanUtils.copyProperties(attr,attr1);
                    return attr1;
                }).collect(Collectors.toList());

                skuESModel.setAttrs(attrs);
            }


            return skuESModel;
        }).collect(Collectors.toList());

        //2，远程调用mall-search服务，将数据存储到ES中
        Boolean aBoolean = esFeginService.saveSkuESModels(skuESModels);

        //3，更新spuId对应的状态
        if (aBoolean){
            SpuInfoEntity spuInfoEntity = new SpuInfoEntity();
            spuInfoEntity.setId(spuId);
            spuInfoEntity.setPublishStatus(ProductConstant.SpuEnum.PUT_ON.getCode());
            this.baseMapper.updateById(spuInfoEntity);
            return R.ok();
        }else {
            return R.error("上架失败!");
        }

    }

}